
// Copyright (c) WanSheng Intelligent Corp. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>
#include "wa_edge_types.h"
#include "cJSON.h"


bool parse_iagent_info(const char * payload, int payload_len, iagent_info_t * info)
{

    bool ret = false;
    cJSON * cfg = cJSON_ParseWithLength(payload,payload_len);
    if(cfg == NULL)
        return false;

    memset(info, 0, sizeof(*info));
    cJSON *item = cJSON_GetObjectItem(cfg, "cloud_status");
    if(item == NULL || item->type != cJSON_Number)
    {
        goto end;
    }
    info->ilink_status = item->valueint;

    item = cJSON_GetObjectItem(cfg, "boot_time");
    if(item == NULL || item->type != cJSON_Number)
    {
        goto end;
    }
    info->iagent_start = item->valueint;


    item = cJSON_GetObjectItem(cfg, "iagent_id");
    if(item && item->type == cJSON_String)
    {
        strncpy(info->iagent_id, item->valuestring, sizeof(info->iagent_id)-1);
    }
    item = cJSON_GetObjectItem(cfg, "cloud");
    if(item && item->type == cJSON_String)
    {
        strncpy(info->cloud_status, item->valuestring, sizeof(info->cloud_status)-1);
    }
    item = cJSON_GetObjectItem(cfg, "project");
    if(item && item->type == cJSON_String)
    {
        strncpy(info->project, item->valuestring, sizeof(info->project)-1);
    }

    ret = true;
end:
    cJSON_Delete(cfg);

    return ret;

}



rd_assemble_t rd_data_init_A(const char * di,
        const char * st,
        const char * dt,
        bool is_alias)
{
    cJSON * JSON_Rd = cJSON_CreateObject();
    cJSON_AddStringToObject(JSON_Rd, is_alias?"alias":"di", di);
    cJSON_AddStringToObject(JSON_Rd, "st", st);
    if(dt)
        cJSON_AddStringToObject(JSON_Rd, "dt", dt);

    return (rd_assemble_t)JSON_Rd;
}

void rd_data_destroy(rd_assemble_t rd)
{
    cJSON * json_rd = (cJSON*) rd;
    cJSON_Delete(json_rd);
}

char * rd_data_payload_A(rd_assemble_t rd)
{
    cJSON * json_rd = (cJSON*) rd;
    return cJSON_PrintUnformatted(json_rd);
}

void rd_data_set_ttl(rd_assemble_t rd, int ttl)
{
    cJSON_AddNumberToObject((cJSON*) rd, "ttl", ttl);
}

void rd_data_set_passive(rd_assemble_t rd)
{
    cJSON * json_rd = (cJSON*) rd;
    char buffer[100] = {0};
    buffer[0] = RD_SET_P_PASSIVE;
    cJSON * current_set = cJSON_GetObjectItem(json_rd, "set");
    if(current_set)
    {
        // already set
        if(strchr(current_set->string, RD_SET_P_PASSIVE) != NULL)
            return;

        strncpy(buffer+1, current_set->string, sizeof(buffer)-2);
    }

    rd_data_set(rd, buffer);
}

void rd_data_set(rd_assemble_t rd, const char * set)
{
    cJSON * json_rd = (cJSON*) rd;
    cJSON_DeleteItemFromObject(json_rd, "set");
    if(set)cJSON_AddStringToObject(json_rd, "set", set);
}




void rd_data_add_resources_cjson(rd_assemble_t rd,
        const char * ri,
        cJSON * rt,
        int * instances,
        int inst_num,
        bool is_rt2)
{
    cJSON * json_rd = (cJSON*) rd;
    cJSON * links = cJSON_GetObjectItem(json_rd, "links");
    cJSON * link;
    if(links == NULL)
    {
        links = cJSON_CreateArray();
        cJSON_AddItemToObject(json_rd, "links",links);
    }

    cJSON_ArrayForEach(link, links)
    {
        cJSON * uri = cJSON_GetObjectItem(link, "href");
        assert (uri != NULL);
        assert (uri->string != NULL);

        // already added
        if(strcmp(uri->string, ri) == 0)
        {
            return;
        }
    }

    cJSON * res = cJSON_CreateObject();
    cJSON_AddStringToObject(res, "href", ri);

    cJSON_AddItemToObject(res, is_rt2?"rt2":"rt", rt);
    if(inst_num && instances)
    {
        cJSON * j_instances = cJSON_CreateIntArray((const int *)instances, inst_num);
        cJSON_AddItemToObject(res, "inst", j_instances);
    }

    cJSON_AddItemToArray(links, res);

}


void rd_data_add_resource_instances(rd_assemble_t rd,
        const char * ri,
        const char * rt,
        int * instances,
        int inst_num)
{

    cJSON * j_rt = cJSON_CreateArray();
    cJSON_AddItemToArray(j_rt, cJSON_CreateString(rt));
    rd_data_add_resources_cjson(rd, ri, j_rt, instances, inst_num, false);
}

void rd_data_add_resource(rd_assemble_t rd, const char * ri, const char * rt)
{
    rd_data_add_resource_instances(rd, ri,rt, NULL, 0);
}
